#include "EbnLink.h"
#include "EbnCondition.h"
#include "EbnCompetenceModule.h"
#include "EbnGoal.h"
#include "EbnModel.h"

CEbnLink::~CEbnLink(void)
{
}

CEbnLink::CEbnLink(CEbnProposition * from, CEbnProposition * to)
{
    mLinkType = NULL_LINK;
    mpSrcProposition = from;
    mpDstProposition = to;

}

void CEbnLink::setDstCompetenceModule(CEbnCompetenceModule * pCompetenceModule)
{
    mpDstCompetenceModule = pCompetenceModule;
    if(mpDstCompetenceModule)
    {
        mpDstCompetenceModule->addToLink(this);
    }
}

CEbnCompetenceModule * CEbnLink::getDstCompetenceModule(void)
{
    return mpDstCompetenceModule;
}

void CEbnLink::setLinkType(LinkType linkType)
{
    mLinkType = linkType;
}

LinkType CEbnLink::getLinkType(void)
{
    return mLinkType;
}

/*
void CEbnLink::setSrcNodeType(SrcNodeType nodeType)
{
    mSrcNodeType = nodeType;
}

SrcNodeType CEbnLink::getSrcNodeType(void)
{
    return mSrcNodeType;
}
*/

CEbnGoalLink::CEbnGoalLink(CEbnProposition * from, CEbnProposition * to)
    : CEbnLink(from, to)
{
    setLinkType(GOAL_LINK);
}

CEbnGoalLink::~CEbnGoalLink(void)
{

}

void CEbnGoalLink::setSrcGoal(CEbnGoal * goal)
{
    mpSrcGoal = goal;
}

CEbnGoal * CEbnGoalLink::getSrcGoal(void)
{
    return mpSrcGoal;
}

bool CEbnGoalLink::isFromGoal(CEbnGoal * goal)
{
    if (mpSrcGoal == goal)
    {
        return true;
    }

    return false;
}


float CEbnGoalLink::getActivation(void)
{
    float activation = 0;

    if (mpSrcGoal->isProtected() && mpSrcGoal->isReached())
    {
        // if it is a protected goal
        activation = - GETPARAM()->getInhibitionOfModule();

    }
    else
    {
        // else if it is a normal goal
        activation = GETPARAM()->getExhibitionOfModule()
                * mpSrcGoal->getImportance();
    }

    return activation;
}

CEbnReceptorLink::CEbnReceptorLink(CEbnProposition * from, CEbnProposition * to)
    : CEbnLink(from, to)
{
    setLinkType(RECEPTOR_LINK);
}

CEbnReceptorLink::~CEbnReceptorLink(void)
{

}

void CEbnReceptorLink::setSrcReceptor(CEbnReceptor * receptor)
{
    mpSrcReceptor = receptor;
}

CEbnReceptor * CEbnReceptorLink::getSrcReceptor(void)
{
    return mpSrcReceptor;
}

bool CEbnReceptorLink::isFromReceptor(CEbnReceptor * receptor)
{
    if (mpSrcReceptor == receptor)
    {
        return true;
    }

    return false;
}

float CEbnReceptorLink::getActivation(void)
{
    float activation = 0;

    if (mpSrcReceptor)
    {
       activation = GETPARAM()->getExhibitionOfState()
                        * mpSrcReceptor->getReception()->getValue();
    }


    return activation;
}

CEbnPredecessorLink::CEbnPredecessorLink(CEbnProposition * from, CEbnProposition * to)
    :CEbnLink(from, to)
{
    setLinkType(PREDECCESSOR_LINK);
}

CEbnPredecessorLink::~CEbnPredecessorLink(void)
{

}

CEbnCondition * CEbnPredecessorLink::getSrcCondition()
{
    if (NULL == mpSrcProposition)
    {
        return NULL;
    }

    return (CEbnCondition *)mpSrcProposition;
}

CEbnEffect * CEbnPredecessorLink::getDstEffect()
{
    if (NULL == mpDstProposition)
    {
        return NULL;
    }

    return (CEbnEffect *)mpDstProposition;

}

bool CEbnPredecessorLink::isFromCompetenceModule(CEbnCompetenceModule * cm)
{
    if (mpSrcCompetenceModule == cm)
    {
        return true;
    }

    return false;
}

CEbnCompetenceModule * CEbnPredecessorLink::getSrcCompetenceModule()
{
    return mpSrcCompetenceModule;
}

void CEbnPredecessorLink::setSrcCompetenceModule(CEbnCompetenceModule * cm)
{
    mpSrcCompetenceModule = cm;
}

float CEbnPredecessorLink::getActivation(void)
{
    float activation = 0;
    float transferredActivation = GETPARAM()->sigmoidTransferFunction(mpSrcCompetenceModule->getActivation());


    if (mpSrcCompetenceModule)
    {
        CEbnEffect * pDstEffect = (CEbnEffect *)mpDstProposition;
        CEbnCondition * pSrcCondition = (CEbnCondition *)mpSrcProposition;

        activation = GETPARAM()->getExhibitionOfModule()
                * GETPARAM()->getExhibitionOfState()
                * transferredActivation
                * (1 - pDstEffect->getValue())
                * mpSrcCompetenceModule->getExecutability()
                * pSrcCondition->getWeight();

    }

    return activation;
}

CEbnSuccessorLink::CEbnSuccessorLink(CEbnProposition * from, CEbnProposition * to)
    :CEbnLink(from, to)
{
    setLinkType(SUCCESSOR_LINK);
}

CEbnSuccessorLink::~CEbnSuccessorLink(void)
{

}

CEbnEffect * CEbnSuccessorLink::getSrcEffect()
{
    if (NULL == mpSrcProposition)
    {
        return NULL;
    }

    return (CEbnEffect *)mpSrcProposition;
}

CEbnCondition * CEbnSuccessorLink::getDstCondition()
{
    if (NULL == mpDstProposition)
    {
        return NULL;
    }

    return (CEbnCondition *)mpDstProposition;

}

bool CEbnSuccessorLink::isFromCompetenceModule(CEbnCompetenceModule * cm)
{
    if (mpSrcCompetenceModule == cm)
    {
        return true;
    }

    return false;
}

CEbnCompetenceModule * CEbnSuccessorLink::getSrcCompetenceModule()
{
    return mpSrcCompetenceModule;
}

void CEbnSuccessorLink::setSrcCompetenceModule(CEbnCompetenceModule * cm)
{
    mpSrcCompetenceModule = cm;
}

float CEbnSuccessorLink::getActivation(void)
{
    float activation = 0;

    float transferredActivation = GETPARAM()->sigmoidTransferFunction(mpSrcCompetenceModule->getActivation());


    if (mpSrcCompetenceModule)
    {
        CEbnEffect * pSrcEffect = (CEbnEffect *)mpSrcProposition;
        CEbnCondition * pDstCondition = (CEbnCondition *)mpDstProposition;


        activation = GETPARAM()->getExhibitionOfModule()
                * GETPARAM()->getExhibitionOfModule()
                * transferredActivation
                * (1 - pSrcEffect->getValue())
                * pDstCondition->getWeight();

    }

    return activation;
}

CEbnConflictorLink::CEbnConflictorLink(CEbnProposition * from, CEbnProposition * to)
    : CEbnLink(from, to)
{
    setLinkType(CONFLICTOR_LINK);
}

CEbnConflictorLink::~CEbnConflictorLink(void)
{

}

bool CEbnConflictorLink::isFromCompetenceModule(CEbnCompetenceModule * cm)
{
    if (mpSrcCompetenceModule == cm)
    {
        return true;
    }

    return false;
}

void CEbnConflictorLink::setSrcCompetenceModule(CEbnCompetenceModule * cm)
{
    mpSrcCompetenceModule = cm;
}

CEbnCompetenceModule * CEbnConflictorLink::getSrcCompetenceModule()
{
    return mpSrcCompetenceModule;
}

float CEbnConflictorLink::getActivation(void)
{
    float activation = 0;
    float transferredActivation = GETPARAM()->sigmoidTransferFunction(mpSrcCompetenceModule->getActivation());

    if(mpSrcCompetenceModule)
    {
        CEbnEffect * pDstEffect = (CEbnEffect *)mpDstProposition;
        CEbnCondition * pSrcCondition = (CEbnCondition *)mpSrcProposition;

        activation = - GETPARAM()->getInhibitionOfModule()
                * GETPARAM()->getExhibitionOfModule()
                * transferredActivation
                * pSrcCondition->getValue()
                * pDstEffect->getWeight();
    }

    return activation;
}

CEbnEffect * CEbnConflictorLink::getSrcEffect()
{
    if (NULL == mpSrcProposition)
    {
        return NULL;
    }

    return (CEbnEffect *)mpSrcProposition;
}

CEbnCondition * CEbnConflictorLink::getDstCondition()
{
    if (NULL == mpDstProposition)
    {
        return NULL;
    }

    return (CEbnCondition *)mpDstProposition;

}
